from flask import Blueprint, jsonify, Response
from flask_restful import Api, Resource, reqparse
from werkzeug.security import generate_password_hash
from common.models.users import *
from celery_task.tasks.sms import *
# from common.utils.redis import MyRedis
from defaults.dev import DevDefaultConfig
import random, redis, string
from sqlalchemy import or_
from common.models import db

from common.utils.login_token import _generate_token
from captcha.image import ImageCaptcha

user_bp = Blueprint("users", __name__, url_prefix="/user")

api = Api(user_bp)


# 注册的接口
class RegisterResource(Resource):
    # 请求方式
    def post(self):
        # 接受前端数据并验证
        parser = reqparse.RequestParser()
        parser.add_argument("username")
        parser.add_argument("password")
        parser.add_argument("phone")
        parser.add_argument("password2")
        args = parser.parse_args()
        username = args.get("username")
        phone = args.get("phone")
        password = args.get("password")
        password2 = args.get("password2")

        # 判断输入的内容是否一致以及是否存在
        if not all([username, password, password2, phone]):
            return jsonify(msg="输入内容不一致",code=204)

        if password != password2:
            return jsonify(msg="两次密码不一致",code=204)

        user =User.query.filter_by(uname=username).first()
        if user:
            return jsonify(msg="用户名存在",code=204)

        user = User.query.filter_by(mobile=phone).first()
        if user:
            return jsonify(msg="手机号存在",code=204)
        # 写入数据库
        user = User(uname=username,mobile=phone,password =generate_password_hash(password))
        db.session.add(user)
        db.session.commit()
        # 返回
        return jsonify(msg="注册成功", code=200)


# 生成短信验证码
class SmsCode(Resource):
    # 请求方式
    def get(self):
        # 接受前端传递的数据并验证
        parser = reqparse.RequestParser()
        parser.add_argument("phone")
        args = parser.parse_args()
        phone = args.get("phone")

        # 生成随机值
        code = random.randint(10000,99999)
        phone = phone
        rest = sms_code(phone, code)
        print("rest>>>", rest)
        # 判断是否发送
        if rest:
            # 发送成功,把短信验证码写入到redis
            rds = redis.Redis(host=DevDefaultConfig.REDIS_HOST ,port=DevDefaultConfig.REDIS_POST,db=DevDefaultConfig.REDIS_DB,password=DevDefaultConfig.REDIS_PASSWORD)
            rds.setex(phone, 60,code)
            # 返回
            return jsonify(message="短信验证码发送成功", code=200)
        # 失败
        else:
            return jsonify(message='短线验证码发送失败', code=500)


# 生成图片验证码
class SmsImage(Resource):
    # 请求方式
    def get(self, uuid):
        # 生成随机的字母大小写和数字
        number = string.ascii_letters + string.digits
        # 在随机的字母和数字中随机选择四个
        img_code = "".join(random.sample(number, 4))
        print("img_code>>>>>>>>>>>>", img_code)

        # 生成图片
        img_cap = ImageCaptcha()
        # 对图片和数字进行拼接
        img_code_cap = img_cap.generate(img_code)
        print("img_code_cap>>>>>>>>>>>>>>>>>>>>>>>>>", img_code_cap)

        # 链接redis
        rds = redis.Redis(host=DevDefaultConfig.REDIS_HOST,port=DevDefaultConfig.REDIS_POST,
                          db=DevDefaultConfig.REDIS_DB,password=DevDefaultConfig.REDIS_PASSWORD)

        key = "image_code:%s"%uuid
        print("key>>>>>>>>>>>>>",key)
        rds.set(key, img_code, ex=300)
        rds.close()

        # 返回
        return Response(img_code_cap, content_type="image/png")


# 登录
class Login(Resource):
    # 请求方式
    def post(self):
        # 接受前端传递的数据并验证
        pars = reqparse.RequestParser()
        pars.add_argument('account')
        pars.add_argument('password')
        pars.add_argument('uuid')
        pars.add_argument('img_code')
        args = pars.parse_args()
        username = args.get("account")
        password = args.get("password")
        uuid = args.get("uuid")
        img_code = args.get("img_code")

        # 链接redis
        rds = redis.Redis(host=DevDefaultConfig.REDIS_HOST,port=DevDefaultConfig.REDIS_POST,
                          db=DevDefaultConfig.REDIS_DB,password=DevDefaultConfig.REDIS_PASSWORD)

        # 根据uuid进行查询
        key = "image_code:%s"%uuid
        img_code_cap = rds.get(key)

        # 判断redis中验证码是否存在
        if not img_code_cap:
            return jsonify(message='验证码已过期', code=500)

        # 判段图形验证码与前端所接受的是否正确
        if img_code.lower() != img_code_cap.decode().lower():
            print("错误》》》》》》》》》》》》》", img_code, img_code_cap)
            return jsonify(message='验证码错误', code=400)

        # 登录成功,生成token
        try:
            user = User.query.filter_by(uname=username).first()
            print("user>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", user)
            data = {'user': user.password,'id': user.uid}
            # 登录生成的token
            token, refresh_token = _generate_token(data, is_refresh=False)
            if token:
                print("判断token》》》》》》》》》》》》》》",token)
                data_ = {'uid': user.uid,'token': token,'refresh_token': refresh_token, "account":user.uname}
                return jsonify(message='登录成功', code=200, data=data_)
            else:
                return jsonify(message='token生成失败', code=500)

        except Exception as e:
            print('获取用户错误',e)
            return jsonify(message='后错误', code=400)

from qiniu import Auth, put_file, etag
def QiNiuYun():
    AccessKey = "Z60NHj0d2Fn746x6thYrsXsUUS8-5452nUARDCcE"
    SecretKey = "ej_fkBU9eXGTCCteK1gP_t0MYjGfrIhAXU9CoCJc"
    q = Auth(AccessKey, SecretKey)

    bucket_name = "ppp8"

    token = q.upload_token(bucket_name)
    return token

# 获取七牛云token
class QiniuToken(Resource):
    def get(self):
        try:
            token = QiNiuYun()
            return jsonify(message="成功",code=200,token=token)
        except Exception as e:
            print("错误", e)
            return jsonify(message="服务器错误！", code=500)


api.add_resource(RegisterResource, "/register") # 注册的路由
api.add_resource(SmsCode, "/phone_code") # 短信验证码的路由
api.add_resource(SmsImage, "/sms_image<uuid:uuid>") # 图形验证码的路由以及uuid
api.add_resource(Login, "/login") # 登录的路由
api.add_resource(QiniuToken, "/qny")














